package com.feige.filter;

import com.feige.cache.CacheTemplate;
import com.feige.constant.Constants;
import com.feige.core.context.AppContext;
import com.feige.entity.SecurityUser;
import com.feige.jwt.JwtTokenHelper;
import com.feige.web.handler.HttpHandler;
import com.feige.web.result.SingleResult;
import lombok.AllArgsConstructor;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * @author feige
 */
@AllArgsConstructor
public class JwtFilter extends OncePerRequestFilter {

    private final CacheTemplate<String, Object> cacheTemplate;

    private final JwtTokenHelper jwtTokenProvider;



    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException, IOException {
        if (!jwtTokenProvider.isExpired(request)) {
            Long loginUserId = AppContext.currentLoginUserId();
            if (loginUserId != null){
                String key = Constants.LOGIN_USER_KEY + loginUserId;
                SecurityUser user = (SecurityUser) cacheTemplate.get(key);
                if (user != null){
                    UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(user, null, user.getAuthorities());
                    authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
                    SecurityContextHolder.getContext().setAuthentication(authenticationToken);
                    chain.doFilter(request, response);
                }else {
                    HttpHandler.renderString(response, SingleResult.noAuth());
                }
            }else {
                HttpHandler.renderString(response, SingleResult.noAuth());
            }
        }else {
            HttpHandler.renderString(response, SingleResult.noAuth());
        }
    }
}
